using System;
using System.Collections;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Xml;
using FormsGenerator.Controls;
using FormsGenerator.Xml;

namespace FormsGenerator
{
	/// <summary>
	/// Summary description for EditElement.
	/// </summary>
	public partial class EditElement : System.Web.UI.Page
	{

		protected XmlDocument formElementsDOM; //The DOM that holds the predefined elements available for editing
		protected XmlDocument formXmlDocument; //The DOM that vil be updated
		protected XmlElement cellElement; //The cell that holds the element being edited
		protected XmlElement itemToEdit; //The item that will be edited
		protected XmlElement elementToEdit; //The html tag (element) that will be edited
		protected XmlElement preSelectedFormsElementType;
 //The matching element that will be preselected in the DropDownList
		protected Hashtable elementAttributes;

		protected void Page_Load(object sender, System.EventArgs e)
		{
			// Put user code to initialize the page here			
			if (ViewState["GUID"] == null || ViewState["position"] == null || ViewState["page"] == null)
			{
				if (Request["id"] == null || Request["id"].Equals("") || Request["position"] == null || Request["position"].Equals("") || Request["page"] == null || Request["page"].Equals(""))
				{
					//TODO: Something here...
				}
				else
				{
					ViewState["GUID"] = Request["id"].Trim();
					ViewState["position"] = Request["position"].Trim();
					ViewState["page"] = Request["page"].Trim();
				}
			}

			try
			{
				formElementsDOM = XmlHandler.GetFormElements();
				formXmlDocument = XmlHandler.GetForm((string) ViewState["GUID"]);
				itemToEdit = XmlHandler.GetItem(formXmlDocument, int.Parse((string) ViewState["page"]), (string) ViewState["position"]);
				if (itemToEdit == null)
				{
					LabelDebug.Text += "<br />Item: null";
				}
				else
				{
					//If editing an existing element
					XmlElement element = (XmlElement)itemToEdit.SelectSingleNode("./element");
					elementToEdit = element.FirstChild as XmlElement;
					string elementTagName = elementToEdit.LocalName.ToLower().Trim();
					preSelectedFormsElementType = (XmlElement)formElementsDOM.SelectSingleNode("/form/elements/element[@name='" + element.GetAttribute("name")+ "']");
					if (preSelectedFormsElementType == null)
					{
						if (elementTagName.Equals("input"))
						{
							preSelectedFormsElementType = (XmlElement)formElementsDOM.SelectSingleNode("/form/elements/element[@tag='" + elementTagName + "' and @type='" + elementToEdit.GetAttribute("type")+ "']");
						}
						else
						{
							preSelectedFormsElementType = (XmlElement)formElementsDOM.SelectSingleNode("/form/elements/element[@tag='" + elementTagName + "']");
						}
					}
				}
			}
			catch (Exception ex)
			{
				LabelErrorMessage.Visible = true;
				LabelErrorMessage.Text += ex.Message;
			}

			if (!IsPostBack)
			{
				//Building type drop down list
				XmlNodeList elementTypes = formElementsDOM.SelectNodes("/form/elements/element");
				DropDownListElementTypes.Items.Clear();

				//If adding a new item...
				//if (itemToEdit == null)
				{
					DropDownListElementTypes.Items.Add(new ListItem("-- select element type --", ""));
				}

				for (int i = 1; i <= elementTypes.Count; i++)
				{
					XmlElement element = (XmlElement) elementTypes[i - 1];
					DropDownListElementTypes.Items.Add(new ListItem(element.GetAttribute("name"), "" + i));
					if (preSelectedFormsElementType != null && element == preSelectedFormsElementType)
					{
						DropDownListElementTypes.SelectedIndex = i;
					}
				}

				Render();
			}
			else
			{
				//HiddenSelectedTab.Value = Request.Form["HiddenSelectedTab"];

			}
		}

		#region Render

		private void Render()
		{
			LabelDebug.Text += "<br />guid: " + ViewState["GUID"] + ", position: " + ViewState["position"] + ", page: " + ViewState["page"];
			//If selected an elementtype
			if (!DropDownListElementTypes.SelectedItem.Value.Trim().Equals(""))
			{
				ButtonSave.Enabled = true;
				//The elementtype
				XmlElement element = (XmlElement) formElementsDOM.SelectSingleNode("/form/elements/element[" + DropDownListElementTypes.SelectedItem.Value + "]");
				XmlNodeList attributes = element.SelectNodes("./attributes");
				String elementDescription = element.GetAttribute("description");
				if (elementDescription != null || !elementDescription.Trim().Equals(""))
				{
					LabelElementDescription.Text = elementDescription;
					PanelElementDescription.Visible = true;
					PanelInstructions.Visible = true;
				}
				else
				{
					PanelElementDescription.Visible = false;
					PanelInstructions.Visible = false;
				}
				//Adding the attributes to the arraylist to later be able to present them in the GUI
				elementAttributes = new Hashtable();
				//If there is an item to edit already. Get the existing items element and get the elements attributes to
				//fill in the existing attribute values in the fields.
				if (itemToEdit != null)
				{
					foreach (XmlAttribute attribute in elementToEdit.Attributes)
					{
						//Exclude the type attribute for input tags
						string attributeName = attribute.Name.ToLower();
						if (!(elementToEdit.LocalName.ToLower().Trim().Equals("input") && attributeName.Equals("type")))
						{
							elementAttributes.Add(attributeName, attribute.Value);
						}
					}
				}

				#region Attributes

				//The new elements attributes. Adding the attributes as Webcontrols on the page.
				//For each attribute there is added a label and description of the attributes functionality.
				//Check if the attribute is mandatory.
				int tabCounter = 1;
				foreach (XmlElement attributesElement in attributes)
				{
					//Adding the header tab for the section
					HtmlTableCell tabCell = new HtmlTableCell();
					HtmlGenericControl tab = new HtmlGenericControl("div");
					string tabString = "General";
					if (!attributesElement.GetAttribute("name").Equals(""))
					{
						tabString = attributesElement.GetAttribute("name");
					}
					tab.Attributes["class"] = "tab";
					tab.ID = "tab" + tabCounter;
					tab.InnerHtml = tabString;
					tab.Attributes["onclick"] = "showTab(" + "tab" + tabCounter + ")";
					tabCell.Controls.Add(tab);
					TableTabs.Rows[0].Cells.Add(tabCell);

					Panel PanelTabContainer = new Panel();
					PanelTabContainer.ID = "container_tab" + tabCounter;
					PanelTabContainer.Attributes["class"] = "tabContainer";
					PanelTabContainer.Style.Add("DISPLAY", "none");

					//Getting the attributes for the formselement.
					XmlNodeList attributeElements = attributesElement.SelectNodes("./attribute");

					foreach (XmlElement attribute in attributeElements)
					{
						string type = attribute.GetAttribute("type");
						string attributeName = attribute.GetAttribute("name").ToLower().Trim();
						Control inputtype = null;
						string inputname = "";
						string atrValue = "";
						//Some different behaviour for the different types
						switch (type)
						{
							case "html":
								inputtype = new HtmlGenericControl("textarea");
								if (elementToEdit != null && !elementToEdit.InnerXml.Equals(""))
								{
									if (elementToEdit.FirstChild.NodeType == XmlNodeType.CDATA)
									{
										((HtmlGenericControl)inputtype).InnerHtml = ((XmlCDataSection)elementToEdit.FirstChild).Data.Trim();
									}
									else
									{
										((HtmlGenericControl)inputtype).InnerHtml = elementToEdit.InnerXml.Trim();	
									}
									
								}
								AddAttributeValue(inputtype, elementAttributes, attributeName);
								if (Application["HTMLEditorInitialScript"] != null)
								{
									string initialScript = Application["HTMLEditorInitialScript"].ToString();
									initialScript = initialScript.Replace("%fieldname%", type + "_" + attribute.GetAttribute("name"));                                    
                                    Page.ClientScript.RegisterStartupScript(this.GetType(),"HtmlEditor", initialScript, true);
								}
								break;
							case "textarea":
								inputtype = new HtmlGenericControl("textarea");
								string numOfRowsForTextarea = attribute.GetAttribute("rows");
								string numOfColsForTextarea = attribute.GetAttribute("cols");
								if (numOfRowsForTextarea.Length > 0)
								{
									((HtmlControl)inputtype).Attributes.Add("rows", numOfRowsForTextarea);
								}
								if (numOfColsForTextarea.Length > 0)
								{
									((HtmlControl)inputtype).Attributes.Add("cols", numOfColsForTextarea);
								}

								if (elementToEdit != null && !elementToEdit.InnerXml.Equals(""))
								{
									((HtmlGenericControl) inputtype).InnerHtml = elementToEdit.InnerXml.Trim();
								}
								AddAttributeValue(inputtype, elementAttributes, attributeName);
								break;
							case "select":
								inputtype = new HtmlSelect();
								//Get value form FormXML
								if (elementAttributes != null && elementAttributes.ContainsKey(attributeName))
								{
									atrValue = elementAttributes[attributeName].ToString().Trim();
									elementAttributes.Remove(attributeName);
								}
								//Get options from formelements.xml
								foreach (XmlElement option in attribute.ChildNodes)
								{
									if (option.HasAttribute("value"))
									{
										string optionValue = option.GetAttribute("value");
										ListItem newOption = new ListItem(option.InnerXml, optionValue);
										//If values match, preselect option 
										if (atrValue.Length > 0 && optionValue.Trim().ToLower().Equals(atrValue.Trim().ToLower()))
										{
											newOption.Selected = true;
										}
										((HtmlSelect) inputtype).Items.Add(newOption);
									}
								}
								break;
							case "checkbox":
								inputtype = new HtmlInputCheckBox();
								if (elementAttributes != null && elementAttributes.ContainsKey(attributeName))
								{
									atrValue = elementAttributes[attributeName].ToString();
									elementAttributes.Remove(attributeName);
									//Make it checked if it's value is "true" or "1"
									if (atrValue.Trim().ToLower().Equals("true") || atrValue.Trim().ToLower().Equals("1"))
									{
										((HtmlInputCheckBox) inputtype).Checked = true;
									}
								}
								break;
							case "checkboxlist":
								string []splitValues = null;
								string delimiter = attribute.GetAttribute("delimiter");
								delimiter = (delimiter == null)? "," : delimiter;
								inputtype = new PlaceHolder();
								inputtype.Controls.Add(new HtmlGenericControl("br"));
								//Get value form FormXML
								if (elementAttributes != null && elementAttributes.ContainsKey(attributeName))
								{
									atrValue = elementAttributes[attributeName].ToString().Trim();
									splitValues = atrValue.Split(delimiter.ToCharArray());
									elementAttributes.Remove(attributeName);
								}
								for (int i = 0; i < attribute.ChildNodes.Count;i++)
								{
									XmlElement option = attribute.ChildNodes[i] as XmlElement;
									if (option.HasAttribute("value"))
									{
										string optionValue = option.GetAttribute("value");
										HtmlInputCheckBox checkBox = new HtmlInputCheckBox();
										checkBox.Name = "checkboxlist_" + attribute.GetAttribute("name") + ":" + i;
										checkBox.ID = "checkboxlist_" + attribute.GetAttribute("name") + ":" + i;
										checkBox.Value = optionValue;
										//If values match, preselect option 
										if (atrValue.Length > 0 && Array.IndexOf(splitValues, optionValue.Trim()) > -1)
										{
											checkBox.Checked = true;
										}
										inputtype.Controls.Add(checkBox );
										
										HtmlGenericControl labelFor = new HtmlGenericControl("label");
										labelFor.Attributes["for"] = checkBox.ClientID;
										labelFor.InnerText = option.InnerXml ;
										inputtype.Controls.Add(labelFor);
										inputtype.Controls.Add(new HtmlGenericControl("br"));
									}
								}
								break;
							default:
								inputtype = new HtmlInputText();
								AddAttributeValue(inputtype, elementAttributes, attributeName);
								break;
						}

						//Create a unique name for the webcontrol
						inputname = type + "_" + attribute.GetAttribute("name");
						inputtype.ID = inputname;
						if (inputtype is HtmlControl)
						{
							//Need this for the textarea
							((HtmlControl)inputtype).Attributes["name"] = inputname;
						} 


						//Check if the attribute is mandatory
						string mandatoryAttribute = attribute.GetAttribute("mandatory");
						bool mandatory = false;
						try
						{
							mandatory = bool.Parse(mandatoryAttribute);
						}
						catch(Exception )
						{
							//Do nothing
						}
						RequiredFieldValidator requiredField = null;

						//Create label in front of the input 
						HtmlGenericControl labelName = new HtmlGenericControl("span");
						labelName.InnerHtml = attribute.GetAttribute("name") + ": ";

						//Adding helptext/description of attribute
						string description = attribute.GetAttribute("description");
						if (description.Length > 0)
						{
							ShowHelpBox.AddOnmousePopupHelp(description, labelName);
						}

						//Add validator if the field is mandatory
						if (mandatory)
						{
							requiredField = new RequiredFieldValidator();
							requiredField.Text = "*";
							requiredField.ErrorMessage = attribute.GetAttribute("name");
							requiredField.ControlToValidate = inputname;
							labelName.Attributes["class"] = "MandatoryLabel";
						}
						PanelTabContainer.Controls.Add(labelName);
						PanelTabContainer.Controls.Add(inputtype);
						if (requiredField != null)
						{
							PanelTabContainer.Controls.Add(requiredField);
						}
						PanelTabContainer.Controls.Add(new HtmlGenericControl("br"));
					}

					#region Select option list					

					if (element.GetAttribute("tag").Equals("select") && tabCounter == 1)
					{
						HtmlGenericControl labelName = new HtmlGenericControl("span");
						labelName.InnerHtml = "Options: ";
						HtmlTextArea inputtype = new HtmlTextArea();
						inputtype.Cols = 35;
						inputtype.Rows = 10;
						inputtype.ID = "options_selectoptions";
						string description = "The options uses | as delimiter for value and text ([value]|[text]). Use a new line for each Option";
						ShowHelpBox.AddOnmousePopupHelp(description, labelName);
						if (elementToEdit != null)
						{
							if (elementToEdit.HasChildNodes)
							{
								string optionTextAreaValue = "";
								foreach (XmlNode option in elementToEdit.ChildNodes)
								{
									if (option.NodeType == XmlNodeType.Element)
									{
										string optionValue = ((XmlElement) option).GetAttribute("value").Trim();
										string optionText = option.InnerXml.Trim();
										if (optionValue == optionText)
										{
											optionTextAreaValue += optionValue + "\n";
										}
										else
										{
											optionTextAreaValue += optionValue + "|" + optionText + "\n";
										}
									}
								}
								inputtype.InnerHtml = optionTextAreaValue;
							}
						}
						PanelTabContainer.Controls.Add(labelName);
						PanelTabContainer.Controls.Add(inputtype);
						PanelTabContainer.Controls.Add(new HtmlGenericControl("br"));

					}
					PanelAttributes.Controls.Add(PanelTabContainer);
					tabCounter++;
				}

				#endregion

				#endregion

				#region Custom attributes

				//Adding custom attributes (not in the formelements.xml file)
				if (elementAttributes != null)
				{
					if (elementAttributes.Count > 0)
					{
						//Adding the header tab for the section
						HtmlTableCell tabCell = new HtmlTableCell();
						HtmlGenericControl tab = new HtmlGenericControl("div");
						tab.Attributes["class"] = "tab";
						tab.ID = "tab" + tabCounter;
						tab.InnerHtml = "Custom";
						tab.Attributes["onclick"] = "showTab(" + "tab" + tabCounter + ")";
						tabCell.Controls.Add(tab);
						TableTabs.Rows[0].Cells.Add(tabCell);

						Panel PanelTabContainer = new Panel();
						PanelTabContainer.ID = "container_tab" + tabCounter;
						PanelTabContainer.Attributes["class"] = "tabContainer";
						PanelTabContainer.Style.Add("DISPLAY", "none");

						foreach (string attribute in elementAttributes.Keys)
						{
							HtmlGenericControl labelName = new HtmlGenericControl("span");
							labelName.InnerHtml = attribute + ": ";
							HtmlInputText inputtype = new HtmlInputText();
							inputtype.ID = "textfield_" + attribute;
							inputtype.Value = (string) elementAttributes[attribute];
							PanelTabContainer.Controls.Add(labelName);
							PanelTabContainer.Controls.Add(inputtype);
							PanelTabContainer.Controls.Add(new HtmlGenericControl("br"));
						}
						PanelAttributes.Controls.Add(PanelTabContainer);
						tabCounter++;
					}
				}

				#endregion

				#region Validation                				

				//Available validations for the selected element
				XmlNodeList validations = element.SelectNodes("./validations/validation");
				//if the item which is beeing edited already has validationelements 
				XmlNodeList elementValidations = null;
				Hashtable itemToEditValidations = new Hashtable();
				if (itemToEdit != null)
				{
					//Adding existing validations from itemToEdit to a hashtable.
					//Use hashtable to preselct validation in GUI.
					elementValidations = itemToEdit.SelectNodes("./validations/validation");
					for (int i = 0; i < elementValidations.Count; i++)
					{
						XmlElement itemValidation = (XmlElement) elementValidations[i];
						string itemValidationId = itemValidation.GetAttribute("id");
						if (itemValidationId.Length > 0)
						{
							//Can only have one unique id
							if (itemToEditValidations.ContainsKey(itemValidationId))
							{
								itemToEditValidations.Add("_" + i, itemValidation);
							}
							else
							{
								itemToEditValidations.Add(itemValidationId, itemValidation);
							}
						}
						else
						{
							//Will be added as custom validation in GUI
							itemToEditValidations.Add("_" + i, itemValidation);
						}
					}
				}

				if (validations.Count > 0 || itemToEditValidations.Count > 0)
				{
					HtmlTableCell tabCell = new HtmlTableCell();
					HtmlGenericControl tab = new HtmlGenericControl("div");
					tab.Attributes["class"] = "tab";
					tab.ID = "tab" + tabCounter;
					tab.InnerHtml = "Validation";
					tab.Attributes["onclick"] = "showTab(" + "tab" + tabCounter + ")";
					tabCell.Controls.Add(tab);
					TableTabs.Rows[0].Cells.Add(tabCell);

					Panel PanelTabContainer = new Panel();
					PanelTabContainer.ID = "container_tab" + tabCounter;
					PanelTabContainer.Attributes["class"] = "tabContainer";
					PanelTabContainer.Style.Add("DISPLAY", "none");

					foreach (XmlElement validation in validations)
					{
						string validationId = validation.GetAttribute("id");
						string validationIsDefault = validation.GetAttribute("default");
						XmlElement elementValidation = (XmlElement)formElementsDOM.SelectSingleNode("/form/validations/validation[@id='" + validationId + "']");
						if (elementValidation != null)
						{
							string validationName = elementValidation.GetAttribute("name");
							string validationDescription = elementValidation.GetAttribute("description");
							HtmlGenericControl labelName = new HtmlGenericControl("label");
							labelName.InnerHtml = validationName + ": ";
							if (validationDescription.Length > 0)
							{
								ShowHelpBox.AddOnmousePopupHelp(validationDescription, labelName);
							}
							HtmlInputCheckBox validationCheckBox = new HtmlInputCheckBox();
							validationCheckBox.ID = "validationSelected_" + validationId;
							labelName.Attributes.Add("for", validationCheckBox.ID);
							HtmlGenericControl validationErrorMessage = new HtmlGenericControl("span");
							validationErrorMessage.InnerHtml = "Error message: ";
							ShowHelpBox.AddOnmousePopupHelp("Add the error message to appear if validation fails.", validationErrorMessage);
							HtmlInputText inputtype = new HtmlInputText();
							inputtype.ID = "validationErrorMessage_" + validationId;
							//inputtype.Value = (string)elementAttributes[attribute];

							Panel PanelValidationAttributes = new Panel();
							PanelValidationAttributes.ID = "PanelValidationAttributes_" + validationId;
							labelName.Attributes["onclick"] = validationCheckBox.Attributes["onclick"] = "showHideField(" + "validationSelected_" + validationId + ", " + "PanelValidationAttributes_" + validationId + ")";
							//Check if the validation already exists in the itemToEdit
							if (itemToEditValidations.ContainsKey(validationId))
							{
								XmlElement itemToEditValidation = (XmlElement) itemToEditValidations[validationId];
								string itemToEditValidationErrorMessage = itemToEditValidation.GetAttribute("errormessage");
								inputtype.Value = itemToEditValidationErrorMessage;
								validationCheckBox.Checked = true;
								itemToEditValidations.Remove(validationId);
							}
							else if (validationIsDefault != null && validationIsDefault == "true")
							{
								validationCheckBox.Checked = true;
							}
							else
							{
								PanelValidationAttributes.Attributes["class"] = "HiddenField";
							}

							PanelValidationAttributes.Controls.Add(validationErrorMessage);
							PanelValidationAttributes.Controls.Add(inputtype);

							PanelTabContainer.Controls.Add(labelName);
							PanelTabContainer.Controls.Add(validationCheckBox);
							//PanelAttributes.Controls.Add(new HtmlGenericControl("br"));
							PanelTabContainer.Controls.Add(PanelValidationAttributes);
							PanelTabContainer.Controls.Add(new HtmlGenericControl("br"));
						}
					}

					//Adding custom validation fields
					//This is for validations that are not specified for this element
					if (itemToEditValidations.Count > 0)
					{
						int validationCustomCounter = 1;
						foreach (XmlElement itemToEditValidation in itemToEditValidations.Values)
						{
							string validationCustomId = itemToEditValidation.GetAttribute("id");
							XmlElement elementValidation = null;
							if (validationCustomId.Length != 0)
							{
								elementValidation = (XmlElement) formElementsDOM.SelectSingleNode("/form/validations/validation[@id='" + validationCustomId + "']");
							}
							//If the validation is not specified in the formsElements, do display it 
							//as it is a custom validation. All existing validations that are specified
							//should not be shown as they are not valid for the selected element.
							if (elementValidation == null)
							{
								HtmlGenericControl labelName = new HtmlGenericControl("label");
								labelName.InnerHtml = "Custom validation " + validationCustomCounter + ": ";
								ShowHelpBox.AddOnmousePopupHelp("This is a custom validation. It is not specified for the selected elementtype. To remove it uncheck the checkbox.", labelName);

								HtmlInputCheckBox validationCheckBox = new HtmlInputCheckBox();
								validationCheckBox.Checked = true;
								validationCheckBox.ID = "validationCustomSelected_" + validationCustomCounter;
								labelName.Attributes.Add("for", validationCheckBox.ID);

								HtmlGenericControl labelValidationCustomErrorMessage = new HtmlGenericControl("span");
								labelValidationCustomErrorMessage.InnerHtml = "Error message: ";
								ShowHelpBox.AddOnmousePopupHelp("Add the error message to appear if validation fails.", labelValidationCustomErrorMessage);

								HtmlInputText textFieldErrorMessage = new HtmlInputText();
								textFieldErrorMessage.ID = "validationCustomErrorMessage_" + validationCustomCounter;
								textFieldErrorMessage.Value = itemToEditValidation.GetAttribute("errormessage");

								XmlNodeList itemToEditExpressions = itemToEditValidation.SelectNodes("./expression");

								Panel PanelValidationAttributes = new Panel();
								PanelValidationAttributes.ID = "PanelCustomValidationAttributes_" + validationCustomCounter;

								PanelTabContainer.Controls.Add(labelName);
								PanelTabContainer.Controls.Add(validationCheckBox);
								labelName.Attributes["onclick"] = validationCheckBox.Attributes["onclick"] = "showHideField(" + "validationCustomSelected_" + validationCustomCounter + ", " + "PanelCustomValidationAttributes_" + validationCustomCounter + ")";

								PanelValidationAttributes.Controls.Add(labelValidationCustomErrorMessage);
								PanelValidationAttributes.Controls.Add(textFieldErrorMessage);
								PanelValidationAttributes.Controls.Add(new HtmlGenericControl("br"));
								for (int i = 0; i < itemToEditExpressions.Count; i++)
								{
									XmlElement validationCustomExpression = (XmlElement) itemToEditExpressions[i];

									HtmlGenericControl labelExpressionLanguage = new HtmlGenericControl("span");
									labelExpressionLanguage.InnerHtml = "RegExp language: ";
									ShowHelpBox.AddOnmousePopupHelp("This specifies the language the regular expression is written for (typical java or vbscript or similar.)", labelExpressionLanguage);

									HtmlInputText textFieldExpressionLanguage = new HtmlInputText();
									textFieldExpressionLanguage.ID = "validationCustomExpressionLanguage_" + validationCustomCounter + "_" + i;
									textFieldExpressionLanguage.Value = validationCustomExpression.GetAttribute("language");

									HtmlGenericControl labelRegularExpression = new HtmlGenericControl("span");
									labelRegularExpression.InnerHtml = "Expression : ";
									ShowHelpBox.AddOnmousePopupHelp("This is the regular expression that validates the input...", labelRegularExpression);

									HtmlInputText textFieldRegularExpression = new HtmlInputText();
									textFieldRegularExpression.ID = "validationCustomRegularExpression_" + validationCustomCounter + "_" + i;
									XmlNode cdataNode = validationCustomExpression.FirstChild;
									if (cdataNode.NodeType == XmlNodeType.CDATA)
									{
										textFieldRegularExpression.Value = ((XmlCDataSection) cdataNode).Data;
									}
									else
									{
										textFieldRegularExpression.Value = cdataNode.Value;
									}

									PanelValidationAttributes.Controls.Add(labelExpressionLanguage);
									PanelValidationAttributes.Controls.Add(textFieldExpressionLanguage);
									PanelValidationAttributes.Controls.Add(new HtmlGenericControl("br"));

									PanelValidationAttributes.Controls.Add(labelRegularExpression);
									PanelValidationAttributes.Controls.Add(textFieldRegularExpression);
									PanelValidationAttributes.Controls.Add(new HtmlGenericControl("br"));

								}
								PanelTabContainer.Controls.Add(PanelValidationAttributes);
								validationCustomCounter++;


								/*
							
									string validationName = elementValidation.GetAttribute("name");
									HtmlGenericControl labelCustomValidationInfo = new HtmlGenericControl("span");
									labelCustomValidationInfo.InnerHtml = "This custom validator is a " + validationName + "validator and is not available for the current element. Please uncheck it to remove it!";
									PanelAttributes.Controls.Add(labelCustomValidationInfo);
									PanelAttributes.Controls.Add(new HtmlGenericControl("br"));
								}
								else
								{
									showExpressions = true;
								}
								*/
							}
						}
					}
					PanelAttributes.Controls.Add(PanelTabContainer);
					tabCounter++;
				}

				#endregion

				HtmlTableCell tabEmptyCell = new HtmlTableCell();
				tabEmptyCell.Attributes["class"] = "tabSpacer";
				tabEmptyCell.InnerHtml = "&nbsp;";
				TableTabs.Rows[0].Cells.Add(tabEmptyCell);
			}
		}

		#endregion

		#region Web Form Designer generated code

		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: This call is required by the ASP.NET Web Form Designer.
			//
			InitializeComponent();
			base.OnInit(e);
		}

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{

		}

		#endregion

		private void AddAttributeValue(Control inputtype, Hashtable elementAttributes, string attributeName)
		{
			//Adding value to the attribute-textfield
			if (elementAttributes != null && elementAttributes.ContainsKey(attributeName))
			{
				((HtmlControl)inputtype).Attributes["value"] = (string) elementAttributes[attributeName];
				//Removing the matching attributes. The leftovers in the collection will be added as custom attributes.
				elementAttributes.Remove(attributeName);
			}
		}

		

		protected void ButtonSave_Click(object sender, System.EventArgs e)
		{
			//Must select an elementtype
			if (DropDownListElementTypes.SelectedItem.Value.Trim().Equals(""))
			{
				LabelErrorMessage.Text += "Please select an itemtype in the list before saving!";
				LabelErrorMessage.Visible = true;
			}
			else
			{
				XmlElement newElementType = (XmlElement) formElementsDOM.SelectSingleNode("/form/elements/element[" + DropDownListElementTypes.SelectedItem.Value + "]");
				Hashtable attributes = new Hashtable();
				ArrayList validations = new ArrayList();
				string[] splitValue;
				string innerHtml = "";
				
				for (int j = 0; j < Request.Form.Keys.Count; j++)
				{
					string name = Request.Form.Keys[j];
					splitValue = name.Split(new Char[] {'_'});
					if (splitValue.Length == 2 && splitValue[0].Equals("textfield"))
					{
						attributes.Add(splitValue[1].ToLower(), Request.Form[name]);
					}
						//Html input 
						//Typical for span tags					
					else if (splitValue.Length == 2 && splitValue[0].Equals("html"))
					{
						innerHtml = "<![CDATA[" + Request.Form[name] + "]]>";
					}
						//textarea
					else if (splitValue.Length == 2 && splitValue[0].Equals("textarea"))
					{
						innerHtml = Request.Form[name];
						//Workaraound for making <textarea></textarea>
						if (innerHtml.Equals(""))
							innerHtml = " ";
					}
						//Select 					
					else if (splitValue.Length == 2 && splitValue[0].Equals("select"))
					{
						attributes.Add(splitValue[1].ToLower(), Request.Form[name]);
					}
						//Checkbox
					else if (splitValue.Length == 2 && splitValue[0].Equals("checkbox"))
					{
						attributes.Add(splitValue[1].ToLower(), "true");
					}
						//CehckBoxList
					else if (splitValue.Length == 2 && splitValue[0].Equals("checkboxlist"))
					{
						XmlElement attributeElement = newElementType.SelectSingleNode(".//attribute[@type='checkboxlist']") as XmlElement;
						string delimiter = attributeElement.GetAttribute("delimiter");
						delimiter = (delimiter == null)? "," : delimiter;
						string[] checkBoxListNameSplit = splitValue[1].Split(new char[]{':'});
						string values = "";
						values +=  Request.Form[name] + delimiter;
						attributes[checkBoxListNameSplit[0]] = attributes[checkBoxListNameSplit[0]] + values;
						
						//Remove last comma in value
						if ( Request.Form.Keys.Count == j + 1 || !Request.Form.Keys[j + 1].StartsWith(splitValue[0] + "_" + checkBoxListNameSplit[0]) )
						{
							attributes[checkBoxListNameSplit[0]] = attributes[checkBoxListNameSplit[0]].ToString().Substring(0, attributes[checkBoxListNameSplit[0]].ToString().Length - 1);
						}
					}
					else if (splitValue.Length == 2 && splitValue[0].Equals("options"))
					{
						innerHtml = Request.Form[name];
						if (innerHtml.Trim().Length > 0)
						{
							string[] options = innerHtml.Split(new Char[] {'\n'});
							innerHtml = "";
							for (int i = 0; i < options.Length; i++)
							{
								string option = options[i];
								if (!(i == (options.Length - 1) && option.Trim().Length == 0))
								{
									string optionValue = "";
									string optionText = "";
									string[] valueText = option.Split(new Char[] {'|'}, 2);
									if (valueText.Length == 1)
									{
										optionValue = optionText = valueText[0].Trim();
									}
									else if (valueText.Length == 2)
									{
										optionValue = valueText[0].Trim();
										optionText = valueText[1].Trim();
									}
									innerHtml += "<option value=\"" + optionValue + "\">" + optionText + "</option>\n";
								}
							}
						}
						//Workaraound for making <textarea></textarea>
						if (innerHtml.Equals(""))
							innerHtml = " ";
					}
						//adding a predefined validation
					else if (splitValue.Length == 2 && splitValue[0].Equals("validationSelected"))
					{
						string validationId = splitValue[1];
						string errorMessage = Request.Form["validationErrorMessage_" + validationId];
						XmlElement validationElement = (XmlElement) formElementsDOM.SelectSingleNode("/form/validations/validation[@id='" + validationId + "']");
						if (validationElement != null)
						{
							Validation validationData = new Validation();
							validationData.ID = validationId;
							validationData.ErrorMessage = errorMessage;
							validationData.Name = validationElement.GetAttribute("name");
							XmlNodeList validationExpressions = validationElement.SelectNodes("./expression");
							Hashtable expressions = new Hashtable();
							foreach (XmlElement expression in validationExpressions)
							{
								string language = expression.GetAttribute("language");
								XmlNode cdataNode = expression.FirstChild;
								string regularExpression = "";
								if (cdataNode.NodeType == XmlNodeType.CDATA)
								{
									regularExpression = ((XmlCDataSection) cdataNode).Data;
								}
								else
								{
									regularExpression = cdataNode.Value;
								}

								if (!expressions.ContainsKey(language))
								{
									expressions.Add(language, regularExpression);
								}
							}
							validationData.RegularExpressions = expressions;
							validations.Add(validationData);
						}
					}
					else if (splitValue.Length == 2 && splitValue[0].Equals("validationCustomSelected"))
					{
						string customValidationId = splitValue[1];
						string errorMessage = Request.Form["validationCustomErrorMessage_" + customValidationId];
						int customRegularExpressionCounter = 0;
						string customRegularExpression = Request.Form["validationCustomRegularExpression_" + customValidationId + "_" + customRegularExpressionCounter];

						Hashtable expressions = new Hashtable();
						while (customRegularExpression != null && customRegularExpression.Length > 0)
						{
							string customRegularExpressionLanguage = Request.Form["validationCustomExpressionLanguage_" + customValidationId + "_" + customRegularExpressionCounter];
							if (!expressions.ContainsKey(customRegularExpressionLanguage))
							{
								expressions.Add(customRegularExpressionLanguage, customRegularExpression);
							}
							customRegularExpressionCounter++;
							customRegularExpression = Request.Form["validationCustomRegularExpression_" + customValidationId + "_" + customRegularExpressionCounter];
						}

						Validation validationData = new Validation();
						validationData.ErrorMessage = errorMessage;
						validationData.RegularExpressions = expressions;
						validations.Add(validationData);
					}
					//LabelDebug.Text += name + "=" + Request.Form[name] + "<br />";
				}

				foreach (string attribute in attributes.Keys)
				{
					LabelDebug.Text += "<br />-" + attribute + ": " + (string) attributes[attribute];
				}

				//If creating new element
				if (itemToEdit == null)
				{
					try
					{
						int page = int.Parse((string) ViewState["page"]);
						itemToEdit = XmlHandler.CreateItem(formXmlDocument, page, (string) ViewState["position"], newElementType, attributes, innerHtml, validations);
						//Check if there are existing items in same cell. Must update position.
						string[] arrPosition = ((string) ViewState["position"]).Split(new Char[] {'_'});
						//If position is x_x_0 then adding new item in a cell that already have items
						if (arrPosition[2].Equals("0"))
						{
							arrPosition[2] = "" + itemToEdit.ParentNode.ChildNodes.Count;
							ViewState["position"] = String.Join("_", arrPosition);
						}
						elementToEdit = (XmlElement) itemToEdit.SelectSingleNode("./element").FirstChild;
						XmlHandler.SaveForm((string) ViewState["GUID"], formXmlDocument, HttpContext.Current.User.Identity.Name);
						LabelExecuteJavascript.Text = "<script>updateForm('" + (string) ViewState["GUID"] + "', false);</script>";
						LabelExecuteJavascript.Visible = true;
					}
					catch (Exception ex)
					{
						LabelErrorMessage.Text += "Error creating element! " + ex.Message + "<br />Go <a href=\"javascript:history.back();\">back</a> and correct the error!";
						LabelErrorMessage.Visible = true;
					}
					LabelDebug.Text += "<br />Adding new element";
				}
					//Editing existing....
				else
				{
					try
					{
						elementToEdit = XmlHandler.EditItem(itemToEdit, newElementType, attributes, innerHtml, validations);
						XmlHandler.SaveForm((string) ViewState["GUID"], formXmlDocument, HttpContext.Current.User.Identity.Name);
						LabelExecuteJavascript.Text = "<script>updateForm('" + (string) ViewState["GUID"] + "', false);</script>";
						LabelExecuteJavascript.Visible = true;
					}
					catch (Exception ex)
					{
						LabelErrorMessage.Text += "Error saving element! " + ex.Message + "<br />Go <a href=\"javascript:history.back();\">back</a> and correct the error!";
						LabelErrorMessage.Visible = true;
					}
					LabelDebug.Text += "<br />Editing existing element";
				}
			}
			Render();
		}

		protected void DropDownListElementTypes_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			Render();
		}
	}
}